﻿using System;
using System.Diagnostics;
using FluentParser.Expressions;

namespace FluentParser.Expressions.Rules.Decoration
{
    /// <summary>
    /// Decorares a symbol by transforming every source
    /// failures into success.
    /// </summary>
    /// <example><code>
    /// Symbol sourceSymbol = Symbol("SomeWord");
    /// Symbol newSymbol = sourceSymbol.Optional("DefaultValue");
    /// 
    /// sourceSymbol.Parse("SomeWord")      --> "SomeWord"
    /// sourceSymbol.Parse("SomeOtherWord") --> failure!
    /// newSymbol.Parse("SomeWord")         --> "SomeWord"
    /// newSymbol.Parse("SomeOtherWord")    --> "DefaultValue"
    /// </code></example>
    [DebuggerDisplay("[OptionalSymbolRule Source={Source} Default={DefaultValue}]")]
    public class OptionalSymbolRule : Symbol 
    {
        public Symbol Source { get; private set; }

        /// <summary> The value used every time a failure is transformed into a success. </summary>
        public string DefaultValue { get; private set; }

        public OptionalSymbolRule(Symbol source, string defaultValue)
        {
            Source = source;
            DefaultValue = defaultValue;
            TypeOperation = OperationType.Decoration;
        }

        public override ParsingResult<object> Parse(GrammarContext context, int index)
        {
            return Source.Parse(context, index) ??
                   new ParsingResult<object>(index, 0, null);
        }

        public override void ParseNode(GrammarContext context, ParsingNodeResult node)
        {
            ParsingNodeResult childNode = node.AddChild(Source, context);
            node.IsSuccess = true;
            node.Value = childNode.IsSuccess ? childNode.Value : String.Empty;
        }
    }
}